﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using UpdaterForm.Annotations;

namespace UpdaterForm.CustomTreeView
{
    public abstract class ATreeNode : INotifyPropertyChanged 
    {

        #region Data

        bool? _isChecked = false;
        ATreeNode _parent;

        #endregion // Data


        public List<ATreeNode> Children { get; set; }
        public bool IsInitiallySelected { get; set; }
        public String Name { get; set; }


        
        public int FileTransfered { get; set; }

        public ATreeNode Root
        {
            get
            {
                var tmp = this;
                while (tmp._parent != null)
                {
                    tmp = tmp._parent;
                }
                return tmp;
            }
        }

        public bool? IsChecked
        {
            get { return _isChecked; }
            set { this.SetIsChecked(value, true, true); }
        }

        void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
        {
            if (value == _isChecked)
                return;

            _isChecked = value;

            if (updateChildren && _isChecked.HasValue)
                this.Children.ForEach(c => c.SetIsChecked(_isChecked, true, false));

            if (updateParent && _parent != null)
                _parent.VerifyCheckState();

            this.OnPropertyChanged("IsChecked");
        }

        void VerifyCheckState()
        {
            bool? state = null;
            for (int i = 0; i < this.Children.Count; ++i)
            {
                bool? current = this.Children[i].IsChecked;
                if (i == 0)
                {
                    state = current;
                }
                else if (state != current)
                {
                    state = null;
                    break;
                }
            }
            this.SetIsChecked(state, false, true);
        }

        protected void SetParent()
        {
            foreach (var child in Children)
            {
                child._parent = this;
                child.Initialize();
            }
        }

        
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private System.IO.DirectoryInfo dir;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) 
                handler(this, new PropertyChangedEventArgs(propName));
        }

        #endregion

        public abstract void Initialize();
        public abstract void Apply(bool Custom);
   
    }
}
